//
// Created by denglibin on 2021/4/7.
//

#ifndef OPENGL_MINGW_GLFW_WINDOW_H
#define OPENGL_MINGW_GLFW_WINDOW_H
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <string>
#include <map>
#include "camera.h"
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>

/**
* 窗口大小改变时的回调函数
* @param window
* @param w
* @param h
*/
void framebufferSizeCallback(GLFWwindow *window, int w, int h);

/**
 * 键盘回调
 * @param window
 * @param key
 * @param scancode
 * @param action
 * @param mods
 */
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);

/**
 * 鼠标回调
 * @param win
 * @param x
 * @param y
 * @return
 */

void mouseCallback(GLFWwindow* win, double x, double y);
/**
 * 滚轮回调
 * @param win
 * @param x_offset
 * @param y_offset
 */
 void scrollCallback(GLFWwindow* win, double x_offset, double y_offset);
/**
 * 窗口类
 */
class Window {
protected:
    /**
     * 保存GLFWwindow 到Window的映射
     */
    static std::map<GLFWwindow*, Window*> m;
    /**
     * 根据GLFWwindow查找Window
     * @param glfW
     * @return
     */
    static Window* findWindow(GLFWwindow* glfW);
    int width = 800;
    int height = 600;
    //标题
    std::string title;
    //使用GLFW
    GLFWwindow* glfwWindow;

    Camera * camera = nullptr;
    /**
     * 初始化操作
     */
    void init();

    /**
     * 释放资源
     */
    void clean();

    /**
     * 绘制
     */
    void virtual paint();

    friend void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
    friend void framebufferSizeCallback(GLFWwindow *window, int w, int h);
    friend void mouseCallback(GLFWwindow* win, double x, double y);
    friend void  scrollCallback(GLFWwindow* win, double x_offset, double y_offset);

public:

    /**
     *无参构造函数
     */
    Window();
    /**
     * 构造函数
     * @param width
     * @param height
     * @param title
     */
    Window(int width, int height, std::string &title);
    /**
     * 析构函数
     */
    ~Window();
    /**
    * 关闭
    */
    void close();
    /**
     * 显示
     */
    void show();

    /**
    * 键盘按下事件
    */
    void keyPressed(int key);

    /**
     * 获取相机
     * @return
     */
    Camera* getCamera();

};


#endif //OPENGL_MINGW_GLFW_WINDOW_H
